import axios from 'axios'

import store from '@/store'// 其實這個導入的就是store裏的getters根
import router from '@/router'
// create an axios instance
const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API,
  // axios请求的完整地址：baseURL+URL
  // 不能让让aixos直接去请求http：//开头的外联地址，而是要请求/开头还要命中本地开发服务器里的代理规则

  // 知识点1：请求的路径问题
  // axios/script标签src/img标签的src/link的href都会发起一次请求
  // 如果是./.开头的地址，找当前文件夹
  // 如果是http开头的地址，找到外链外部服务器（链接网路）
  // 如果是/开头的地址，忽略文件夹，直接找到当前运行时，所在服务器
  // url = base url + request url
  // withCredentials: true, // send cookies when cross-domain requests
  timeout: 5000 // request timeout
})

// request interceptor
service.interceptors.request.use(
  // config是内置的
  config => {
    // 知識點：js文件中不能使用this.$store,因爲this關鍵字不是ve組件對象，無法查找原型鏈上的$store
    // 但是this.$store爲了拿到store/index.js必須要導出store對象
    // 解決：直接把store對戲導入過啦使用，是同i個store
    // 取出token
    const token = store.getters.token// 從store文件下的getters的文件裏取出token
    // 開始判斷是否有token的值
    if (token) {
      config.headers.Authorization = `Bearer ${token}`
    }
    return config
  },
  error => {
    return Promise.reject(error)
  }
)

// response interceptor响应拦截
// 知识点1：axiose内部的处理机制
// 方式1：http状态码处理
// 1.http状态码为2xx，3xx就会给Primise对象位置，返回成功的结果（resolve（））
// 2.http状态码为4xx，xx，就会给Primise对象位置，返回错误的结果（reject（））
// 如果想做一些操作，可以在aixos的响应拦截器，自己处理返回的结果
// 补充：http状态码，有本次请求后，后端进行设置返回
// 方式2：后台返回的对象里code字段/success字段（逻辑字段 判断）
service.interceptors.response.use(
  response => { // http为2xx，3xx进入这里
    // 本项目成功/失败都是2xx响应状态码，都进入这里所以需要根据字段判定
    // console.log(response)// 打印出来的是实例对象数据
    // 结构===赋值
    const { success, message } = response.data
    // 判断,如果success返回是false失败
    if (success === false) {
      // 给个提示
      return Promise.reject(new Error(message))
    } else {
      // 成功
      // 现在要做的是response给他解构出来，这样让index页面，可以不用res.data.message，。就是多解构一个，代码冗余
      // console.log(response.data)//打印出来的是data数据
      // response返回的是axios处理的结果对象（逻辑那边的.data.data）拿到后台返回值
      return response.data// 特殊：它返回到的是axios调用在原地留下的''Promise''对象位置（路基页面await后面）
    }
  },
  error => { // http为4xx ，5xx进入这里
    // 身份过期，后台双重返回401，逻辑状态码
    // 前置非空判断（eror有值，才会执行&&后面的代码）
    // 确保error有值，在response，。reponse有值，在.status
    // 防止null.xxx语法报错代码停止
    // if(error&&error.response&&error.response.satus===401)//身份过期，删除所有cookie，重置vuex，强制回到登录页面
    // 但是账号密码失败的时候返回的是200，用逻辑判断，最好统一
    // code更好，因为401如果有多情况，success只能判断是失败，可以跟后台商量code值不同
    // 10000成功 10002身份过期，
    // { console.dir(error) }
    if (error.response.data.code === 10002) { // 身份过期
      store.commit('user/RESET_STATE')// 获取本地token
      store.commit('user/REMOVE_TOKEN')// 内部会删除本地token
      // router.replace('/login')
      console.log(router.currentRouter)
      // router.currentRouter路由对象内置的，也拿到当前页面路由的信息

      // 路由跳转到登入页面尾随的地址完整地址================================未遂地址：退出登入所在页面路由完整路径
      // 主动退出
      router.replace(`/login?redirect=${encodeURIComponent(router.currentRouter.fullPath)}`)// 老师写法
      // router.replace(`/login?path=${router.currentRoute.fullPath}`)
      // 效果：手动/等2小时，让本地cookie里token过期，刷新网页会强制退回登录页面
    }
    return Promise.reject(error)// 相当于reject（error）
  }
)

export default service
